/*
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Feb 23, 2011
 * Time: 8:38:25 PM
 */
package util

/**
 * This object is used when a series of calls is to be performed in which each invocation returns an Option result and
 * it would be inconvenient to handle each Option result in a match block. Object Deopt allows the programmer to
 * linearize the invocations.
 * <pre>
 *    import util.Deopt._
 *
 *    val metaSource: ProjectMetaDataSource = ...
 *
 *    deopt(
 *     deopt(
 *       deopt(
 *         metaSource.projectMetaData(locale)).projectEntryMeta(entry)).title, defaultTitle)
 * </pre>
 *
 * All methods <code>projectMetaData</code>, <code>projectEntryMeta</code> and <code>title</code> are supposed to
 * return an Option result. DefaultValueSignal exception is thrown as long as value None is returned by some method and
 * the default value for this invocation is not specified.
 */
object Deopt {

  class DefaultValueSignal extends Throwable

  def deopt[Z](v: => Option[Z], defVal: => Z = {throw new DefaultValueSignal}): Z = {
    try {
      v match {
        case None => defVal
        case Some(z) => z
      }
    }
    catch {
      case s: DefaultValueSignal => defVal
    }
  }

}